<script setup lang="ts">
import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
import SockJS from 'sockjs-client'
import { Client } from '@stomp/stompjs'

interface Cell {
  isMine: boolean
  isRevealed: boolean
  isPlayer1: boolean
  adjacentMines: number
  revealedBy: number[]
}

interface GameState {
  isConnected: boolean
  roomId: string
  playerId: string
  isWaiting: boolean
  canPlay: boolean
  isPlayer1: boolean
  isCreator: boolean
  userId: string
  phase: string
  currentPlayer: number
  player1Mines: { row: number; col: number }[]
  player2Mines: { row: number; col: number }[]
  player1Guesses: number[]
  player2Guesses: number[]
  gameOver: boolean
  winner: string
  board: Cell[][]
  gamePhase: 'placing' | 'playing' | 'gameOver'
  player1Alive: boolean
  player2Alive: boolean
  gameOverMessage: string
  toastMessage: string
  toastVisible: boolean
  punishment: string
  minesPlaced: number
  minesPerPlayer: number
}

interface GameMessage {
  type: string
  roomId?: string
  playerId?: string
  action?: string
  row?: number
  col?: number
  gameState?: GameState
  loserId?: string
  userId?: string
}

const GRID_SIZE = 5
const MINES_PER_PLAYER = 1
const gameStarted = ref(false)
const ws = ref<Client | null>(null)

const punishments = [
  '做10个俯卧撑',
  '唱一首歌',
  '模仿一个动物',
  '讲一个笑话',
  '跳一段舞',
  '做20个深蹲',
  '表演一个魔术',
  '模仿一个名人',
  '做30个仰卧起坐',
  '讲一个故事'
]

// 修改用户标识符生成和获取函数
const getStoredUserId = () => {
  const storedId = localStorage.getItem('minesweeper_user_id')
  if (storedId) {
    return storedId
  }
  const newId = generateUserId()
  localStorage.setItem('minesweeper_user_id', newId)
  return newId
}

const generateUserId = () => {
  return 'user_' + Math.random().toString(36).substr(2, 9)
}

const gameState = reactive<GameState>({
  isConnected: false,
  roomId: '',
  playerId: '',
  isWaiting: false,
  canPlay: false,
  isPlayer1: false,
  isCreator: false,
  userId: getStoredUserId(),
  phase: 'PLACE_MINES',
  currentPlayer: 1,
  player1Mines: [],
  player2Mines: [],
  player1Guesses: [],
  player2Guesses: [],
  gameOver: false,
  winner: '',
  board: Array(GRID_SIZE).fill(null).map(() => 
    Array(GRID_SIZE).fill(null).map(() => ({
      isMine: false,
      isRevealed: false,
      isPlayer1: false,
      adjacentMines: 0,
      revealedBy: []
    }))
  ),
  gamePhase: 'placing',
  player1Alive: true,
  player2Alive: true,
  gameOverMessage: '',
  toastMessage: '',
  toastVisible: false,
  punishment: '',
  minesPlaced: 0,
  minesPerPlayer: MINES_PER_PLAYER
})

const getRemainingMines = (player: number) => {
  const placedMines = gameState.board.flat().filter(cell => 
    cell.isMine && cell.isPlayer1 === (player === 1)
  ).length
  return MINES_PER_PLAYER - placedMines
}

// 修改WebSocket连接函数
const connectWebSocket = () => {
  try {
    console.log('开始连接WebSocket...')
    const socket = new SockJS('/ws/game')
    ws.value = new Client({
      webSocketFactory: () => socket,
      connectHeaders: {
        'heart-beat': '10000,10000'
      },
      debug: (str) => {
        console.log('STOMP: ' + str);
      },
      reconnectDelay: 5000,
      heartbeatIncoming: 4000,
      heartbeatOutgoing: 4000,
      onConnect: () => {
        console.log('WebSocket连接成功')
        gameState.isConnected = true
        gameState.isWaiting = false
        gameState.roomId = ''
        gameState.playerId = ''
        gameState.isPlayer1 = false
        gameState.isCreator = false
        showToast('已连接到服务器')
        
        // 订阅游戏消息
        ws.value?.subscribe('/topic/game', (message) => {
          try {
            console.log('收到消息:', message.body)
            const data = JSON.parse(message.body)
            handleWebSocketMessage(data)
          } catch (error) {
            console.error('消息解析错误:', error)
          }
        })
      },
      onDisconnect: () => {
        console.log('WebSocket断开连接')
        gameState.isConnected = false
        showToast('与服务器断开连接')
        // 尝试重新连接
        setTimeout(() => {
          if (!gameState.isConnected) {
            console.log('尝试重新连接...')
            connectWebSocket()
          }
        }, 5000)
      },
      onStompError: (frame) => {
        console.error('STOMP error:', frame)
        showToast('连接错误：' + frame.headers.message)
        // 发生错误时尝试重新连接
        setTimeout(() => {
          if (!gameState.isConnected) {
            console.log('尝试重新连接...')
            connectWebSocket()
          }
        }, 5000)
      }
    })

    ws.value.activate()
  } catch (error) {
    console.error('WebSocket连接错误:', error)
    showToast('连接失败，请检查服务器状态')
    // 连接失败时尝试重新连接
    setTimeout(() => {
      if (!gameState.isConnected) {
        console.log('尝试重新连接...')
        connectWebSocket()
      }
    }, 5000)
  }
}

// 测试服务器连接
const testServerConnection = async () => {
  try {
    const response = await fetch('/api/test', {
      method: 'GET',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      }
    })
    
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }
    
    const data = await response.text()
    console.log('服务器测试响应:', data)
    return true
  } catch (error) {
    console.error('服务器连接测试失败:', error)
    showToast('无法连接到服务器，请检查服务器状态')
    return false
  }
}

// 发送消息
const sendMessage = (message: GameMessage) => {
  if (ws.value?.connected) {
    ws.value.publish({
      destination: '/app/gameAction',
      body: JSON.stringify(message)
    })
  } else {
    showToast('未连接到服务器')
  }
}

// 修改handleWebSocketMessage函数
const handleWebSocketMessage = (message: any) => {
  console.log('处理消息:', message)
  console.log('当前用户ID:', gameState.userId)
  console.log('消息用户ID:', message.userId)
  
  switch (message.type) {
    case 'ROOM_CREATED':
      console.log('房间创建成功，房间号:', message.roomId)
      if (message.userId === gameState.userId) {
        gameState.roomId = message.roomId
        gameState.playerId = message.playerId
        gameState.isWaiting = true
        gameState.canPlay = true
        gameState.isPlayer1 = true
        gameState.isCreator = true
        gameState.phase = 'PLACE_MINES'
        gameState.currentPlayer = 1
        showToast(`房间创建成功，房间号: ${message.roomId}，等待其他玩家加入...`)
      }
      break
      
    case 'PLAYER_JOINED':
      console.log('玩家加入消息:', message)
      if (gameState.isCreator) {
        gameState.isWaiting = false
        gameStarted.value = true
        gameState.canPlay = true
        gameState.phase = 'PLACE_MINES'
        gameState.currentPlayer = 1
        showToast('对手已加入，游戏开始！')
      } else if (gameState.roomId === message.roomId) {
        gameState.isWaiting = false
        gameStarted.value = true
        gameState.canPlay = false
        gameState.isPlayer1 = false
        gameState.phase = 'PLACE_MINES'
        gameState.currentPlayer = 1
        showToast('成功加入房间，游戏开始！')
      }
      break
      
    case 'GAME_UPDATE':
      console.log('游戏状态更新:', message.gameState)
      if (gameState.roomId === message.roomId) {
        console.log('更新前的游戏状态:', {
          phase: gameState.phase,
          canPlay: gameState.canPlay,
          isPlayer1: gameState.isPlayer1,
          currentPlayer: gameState.currentPlayer,
          gamePhase: gameState.gamePhase
        })
        updateGameState(message.gameState)
        // 修改canPlay的判断逻辑
        if (message.gameState.gamePhase === 'placing') {
          // 放置地雷阶段，玩家1可以放置
          gameState.canPlay = gameState.isPlayer1 && gameState.player1Mines.length < 1
          console.log('放置地雷阶段，玩家1状态:', {
            isPlayer1: gameState.isPlayer1,
            canPlay: gameState.canPlay,
            minesCount: gameState.player1Mines.length
          })
          if (gameState.canPlay) {
            showToast('请放置你的地雷')
          } else if (gameState.isPlayer1) {
            showToast('等待对手放置地雷...')
          }
        } else {
          // 排雷阶段，根据当前玩家判断
          gameState.canPlay = (gameState.isPlayer1 && message.gameState.currentPlayer === 1) ||
                             (!gameState.isPlayer1 && message.gameState.currentPlayer === 2)
          console.log('排雷阶段，玩家状态:', {
            isPlayer1: gameState.isPlayer1,
            currentPlayer: message.gameState.currentPlayer,
            canPlay: gameState.canPlay
          })
          if (!gameState.canPlay) {
            showToast('等待对手操作...')
          }
        }
      }
      break
      
    case 'GAME_OVER':
      console.log('游戏结束消息:', message)
      if (gameState.roomId === message.roomId) {
        gameState.gameOver = true
        gameState.winner = message.winner
        gameState.canPlay = false
        gameState.gamePhase = 'gameOver'
        
        // 显示游戏结束提示
        const randomPunishment = punishments[Math.floor(Math.random() * punishments.length)]
        gameState.punishment = randomPunishment
        
        // 根据当前玩家身份显示不同的提示
        if (message.winner === (gameState.isPlayer1 ? 'player1' : 'player2')) {
          gameState.gameOverMessage = `恭喜你获胜！\n惩罚：${randomPunishment}`
          showToast('恭喜你获胜！')
        } else {
          gameState.gameOverMessage = `很遗憾，你输了！\n惩罚：${randomPunishment}`
          showToast('很遗憾，你输了！')
        }
        
        // 3秒后自动开始新的一局
        setTimeout(() => {
          resetGame()
        }, 3000)
      }
      break
  }
}

// 修改updateGameState函数
const updateGameState = (newState: any) => {
  console.log('更新游戏状态:', newState)
  // 更新基本状态
  gameState.phase = newState.phase || gameState.phase
  gameState.currentPlayer = newState.currentPlayer || gameState.currentPlayer
  gameState.gamePhase = newState.gamePhase || gameState.gamePhase
  gameState.player1Mines = newState.player1Mines || gameState.player1Mines
  gameState.player2Mines = newState.player2Mines || gameState.player2Mines
  gameState.player1Guesses = newState.player1Guesses || gameState.player1Guesses
  gameState.player2Guesses = newState.player2Guesses || gameState.player2Guesses
  gameState.gameOver = newState.gameOver || gameState.gameOver
  gameState.winner = newState.winner || gameState.winner
  gameState.player1Alive = newState.player1Alive
  gameState.player2Alive = newState.player2Alive
  
  // 更新棋盘显示
  if (newState.board) {
    // 创建新的棋盘状态，根据用户ID过滤地雷显示
    const filteredBoard = newState.board.map((row: any[]) => 
      row.map((cell: any) => {
        const newCell = { ...cell }
        // 如果是地雷，检查是否应该显示
        if (newCell.isMine) {
          // 如果是玩家1的地雷，且当前用户是玩家1，则显示
          if (newCell.isPlayer1 && gameState.isPlayer1) {
            newCell.isRevealed = true
          }
          // 如果是玩家2的地雷，且当前用户是玩家2，则显示
          else if (!newCell.isPlayer1 && !gameState.isPlayer1) {
            newCell.isRevealed = true
          }
          // 其他情况显示为未点击状态（灰色格子）
          else {
            newCell.isRevealed = false
          }
        }
        return newCell
      })
    )
    gameState.board = filteredBoard
    console.log(gameState.board)
  }
}

// 修改createRoom函数
const createRoom = () => {
  if (ws.value?.connected) {
    console.log('开始创建房间...')
    gameState.isPlayer1 = true
    gameState.isCreator = true
    gameState.isWaiting = true
    gameState.canPlay = true
    gameState.roomId = ''  // 先清空房间号，等待服务器返回
    ws.value.publish({
      destination: '/app/createRoom',
      body: JSON.stringify({
        type: 'CREATE_ROOM',
        playerId: 'player1',
        userId: gameState.userId
      })
    })
    showToast('正在创建房间...')
  } else {
    showToast('未连接到服务器，请稍后重试')
  }
}

// 添加一个本地变量来存储输入的房间号
const inputRoomId = ref('')

// 修改joinRoom函数
const joinRoom = (roomId: string) => {
  if (ws.value?.connected) {
    console.log('加入房间:', roomId)
    gameState.isPlayer1 = false
    gameState.isCreator = false
    gameState.isWaiting = true
    gameState.canPlay = false
    gameState.roomId = roomId  // 设置房间号
    ws.value.publish({
      destination: '/app/joinRoom',
      body: JSON.stringify({
        type: 'JOIN_ROOM',
        roomId: roomId,
        playerId: 'player2',
        userId: gameState.userId
      })
    })
    showToast('正在加入房间...')
  } else {
    showToast('未连接到服务器，请稍后重试')
  }
}

// 修改sendGameAction函数
const sendGameAction = (action: string, row: number, col: number) => {
  if (ws.value?.connected) {
    sendMessage({
      type: 'GAME_ACTION',
      action: action,
      row: row,
      col: col,
      roomId: gameState.roomId,
      playerId: gameState.isPlayer1 ? 'player1' : 'player2',
      userId: gameState.userId
    })
  }
}

// 修改placeMine函数
const placeMine = (row: number, col: number) => {
  if (gameState.gamePhase !== 'placing') return
  if (gameState.board[row][col].isMine) return
  let remainingMines = 0;
  if(gameState.isPlayer1){
    remainingMines = getRemainingMines(1)
  }else{
    remainingMines = getRemainingMines(2)
  }
  if (remainingMines <= 0) return
  
  sendGameAction('PLACE_MINE', row, col)
}

// 修改revealCell函数
const revealCell = (row: number, col: number) => {
  if (gameState.gamePhase !== 'playing') return
  if (!gameState.canPlay) {
    showToast('请等待对手操作')
    return
  }
  
  const cell = gameState.board[row][col]
  if (cell.isRevealed) {
    showToast('该格子已被翻开，请选择其他格子')
    return
  }
  if (cell.revealedBy.includes(gameState.currentPlayer)) return
  
  // 检查是否是对方的地雷
  if (cell.isMine && cell.isPlayer1 !== gameState.isPlayer1) {
    // 发送游戏结束消息
    sendGameAction('REVEAL_CELL', row, col)
    gameState.canPlay = false
    // 显示游戏结束提示
    const randomPunishment = punishments[Math.floor(Math.random() * punishments.length)]
    gameState.punishment = randomPunishment
    gameState.gameOverMessage = `游戏结束！你踩到了对方的地雷！\n惩罚：${randomPunishment}`
    return
  }
  
  sendGameAction('REVEAL_CELL', row, col)
  gameState.canPlay = false
}

// 组件挂载时连接WebSocket
onMounted(async () => {
  // 先测试服务器连接
  const isServerAvailable = await testServerConnection()
  if (isServerAvailable) {
    connectWebSocket()
  } else {
    showToast('无法连接到服务器，请检查服务器状态')
  }
})

// 组件卸载时关闭WebSocket连接
onUnmounted(() => {
  if (ws.value) {
    ws.value.deactivate()
  }
})

// 暴露状态给模板
const { player1Alive, player2Alive } = gameState

const getPlayerStatus = computed(() => {
  if (!gameStarted.value) return ''
  const playerNumber = gameState.isPlayer1 ? '1' : '2'
  if (gameState.gamePhase === 'placing') {
    return gameState.canPlay ? `轮到您（玩家${playerNumber}）放置地雷` : '等待对手放置地雷'
  } else {
    return gameState.canPlay ? `轮到您（玩家${playerNumber}）翻开格子` : '等待对手操作'
  }
})

function showToast(msg: string) {
  gameState.toastMessage = msg
  gameState.toastVisible = true
  setTimeout(() => {
    gameState.toastVisible = false
  }, 2000)
}

// 修改showRoomActions计算属性
const showRoomActions = computed(() => {
  return gameState.isConnected && !gameStarted.value && !gameState.isWaiting && !gameState.roomId
})

// 修改showWaitingScreen计算属性
const showWaitingScreen = computed(() => {
  return gameState.isWaiting && (gameState.isCreator || gameState.roomId) && !gameStarted.value
})

// 修改showGameRules计算属性
const showGameRules = computed(() => {
  return !gameStarted.value && !gameState.isWaiting && !gameState.roomId
})

// 修改resetGame函数
const resetGame = () => {
  // 重置游戏状态
  gameState.board = Array(GRID_SIZE).fill(null).map(() => 
    Array(GRID_SIZE).fill(null).map(() => ({
      isMine: false,
      isRevealed: false,
      isPlayer1: false,
      adjacentMines: 0,
      revealedBy: []
    }))
  )
  gameState.currentPlayer = 1
  gameState.gamePhase = 'placing'
  gameState.player1Alive = true
  gameState.player2Alive = true
  gameState.gameOverMessage = ''
  gameState.punishment = ''
  gameState.gameOver = false
  gameState.winner = ''
  gameState.player1Mines = []
  gameState.player2Mines = []
  gameState.player1Guesses = []
  gameState.player2Guesses = []
  
  // 保持房间和玩家信息不变
  // gameState.roomId = ''
  // gameState.playerId = ''
  // gameState.isWaiting = false
  // gameState.canPlay = false
  // gameState.isPlayer1 = false
  // gameState.isCreator = false
  // gameStarted.value = false
  
  // 设置玩家状态
  if (gameState.isCreator) {
    gameState.canPlay = true
    gameState.isWaiting = true
    showToast('等待对手加入新的一局...')
  } else {
    gameState.canPlay = false
    showToast('等待房主开始新的一局...')
  }
}

// 添加清除用户标识符的函数
const clearUserIdentity = () => {
  localStorage.removeItem('minesweeper_user_id')
  gameState.userId = generateUserId()
  localStorage.setItem('minesweeper_user_id', gameState.userId)
}

// 添加用户身份显示
const getUserIdentity = computed(() => {
  return `用户ID: ${gameState.userId.substring(0, 8)}...`
})


// 修改模板中的地雷显示逻辑
const getCellClass = (cell: any) => {
  const classes = ['cell']
  
  if (cell.isRevealed) {
    classes.push('revealed')
    if (cell.isMine) {
      // 只有地雷的所有者才能看到地雷
      if ((cell.isPlayer1 && gameState.isPlayer1) || (!cell.isPlayer1 && !gameState.isPlayer1)) {
        classes.push('mine')
      }
    } else {
      classes.push('safe')
    }
  } else {
    classes.push('hidden')
  }
  
  return classes
}
</script>

<template>
  <transition name="toast-fade">
    <div v-if="gameState.toastVisible" class="toast-bar">
      {{ gameState.toastMessage }}
    </div>
  </transition>
  <transition name="fade-scale">
    <div v-if="gameState.gameOverMessage" class="game-over-modal">
      <div class="game-over-content">
        <div class="game-over-icon">💥</div>
        <div class="game-over-title">游戏结束</div>
        <div class="game-over-msg">{{ gameState.gameOverMessage }}</div>
        <div class="punishment-text">{{ gameState.punishment }}</div>
        <button class="restart-btn" @click="resetGame">🔄 重新开始</button>
      </div>
    </div>
  </transition>
  <div class="game-container">
    <div class="game-info">
      <h2 class="game-title">
        <span class="icon">💣</span>
        扫雷对战
        <span class="icon">💣</span>
      </h2>
      
      <!-- 连接状态和用户身份 -->
      <div class="status-section">
        <div class="connection-status" :class="{ connected: gameState.isConnected }">
          <span class="status-dot"></span>
          {{ gameState.isConnected ? '已连接' : '未连接' }}
        </div>
        <div class="user-identity">
          {{ getUserIdentity }}
          <button class="reset-identity-btn" @click="clearUserIdentity">
            切换身份
          </button>
        </div>
      </div>
      
      <!-- 房间操作 -->
      <div v-if="showRoomActions" class="room-actions">
        <div class="action-buttons">
          <button class="action-btn create" @click="createRoom">
            <span class="icon">🏠</span>
            创建房间
          </button>
          <div class="join-room">
            <input 
              type="text" 
              v-model="inputRoomId" 
              placeholder="输入房间号"
              :disabled="gameState.isWaiting"
            >
            <button 
              class="action-btn join" 
              @click="joinRoom(inputRoomId)"
              :disabled="gameState.isWaiting || !inputRoomId"
            >
              <span class="icon">🚪</span>
              加入房间
            </button>
          </div>
        </div>
      </div>
      
      <!-- 等待对手 -->
      <div v-if="showWaitingScreen" class="waiting-screen">
        <div class="waiting-content">
          <div class="loading-spinner"></div>
          <h3>{{ gameState.isCreator ? '等待对手加入...' : '正在加入房间...' }}</h3>
          <p class="room-id" v-if="gameState.roomId">房间号: {{ gameState.roomId }}</p>
          <p class="room-id" v-else>正在处理...</p>
        </div>
      </div>

      <!-- 游戏说明 -->
      <div class="game-rules" v-if="showGameRules">
        <div class="rules-header">
          <h3>
            <span class="icon">📖</span>
            游戏规则
          </h3>
        </div>
        <div class="rules-content">
          <div class="rule-item">
            <span class="rule-icon">1️⃣</span>
            <p>游戏分为两个阶段：放置地雷和排雷</p>
          </div>
          <div class="rule-item">
            <span class="rule-icon">2️⃣</span>
            <p>每个玩家只能放置1个地雷</p>
          </div>
          <div class="rule-item">
            <span class="rule-icon">3️⃣</span>
            <p>放置完成后，玩家轮流猜测地雷位置</p>
          </div>
          <div class="rule-item">
            <span class="rule-icon">4️⃣</span>
            <p>猜中对方的地雷时，对方阵亡</p>
          </div>
          <div class="rule-item">
            <span class="rule-icon">5️⃣</span>
            <p>最后存活的玩家获胜！</p>
          </div>
        </div>
      </div>

      <div v-else-if="gameStarted" class="game-rules">
        <div class="rules-header">
          <h3>
            <span class="icon">🎮</span>
            游戏进行中
          </h3>
        </div>
        <div class="rules-content">
          <div class="status-section">
            <div class="status-card phase-card" :class="{ active: gameState.gamePhase === 'placing' }">
              <h3>
                <span class="icon">🎯</span>
                游戏阶段
              </h3>
              <p>{{ gameState.gamePhase === 'placing' ? '放置地雷' : '游戏进行中' }}</p>
              <p class="player-status">{{ getPlayerStatus }}</p>
            </div>
          </div>
          
          <div class="status-section players-section">
            <div class="status-card" :class="{ active: gameState.currentPlayer === 1 }">
              <h3>
                <span class="icon">👤</span>
                玩家1
              </h3>
              <p>{{ player1Alive ? '存活' : '阵亡' }}</p>
              <p class="mine-count" v-if="gameState.gamePhase === 'placing'">
                剩余地雷: {{ getRemainingMines(1) }}
              </p>
            </div>
            <div class="status-card" :class="{ active: gameState.currentPlayer === 2 }">
              <h3>
                <span class="icon">👤</span>
                玩家2
              </h3>
              <p>{{ player2Alive ? '存活' : '阵亡' }}</p>
              <p class="mine-count" v-if="gameState.gamePhase === 'placing'">
                剩余地雷: {{ getRemainingMines(2) }}
              </p>
            </div>
          </div>
          <div class="board">
            <div v-for="(row, rowIndex) in gameState.board" :key="rowIndex" class="row">
              <div
                v-for="(cell, colIndex) in row"
                :key="colIndex"
                class="cell"
                :class="getCellClass(cell)"
                @click="gameState.gamePhase === 'placing' ? placeMine(rowIndex, colIndex) : revealCell(rowIndex, colIndex)"
              >
                <template v-if="cell.isRevealed">
                  <span v-if="cell.isMine" class="mine-icon">💣</span>
                  <span v-else>🟩</span>
                </template>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.game-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 36px;
  padding: 48px 4vw;
  background: white;
  border-radius: 28px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.13);
  width: 100%;
  max-width: 800px;
  margin: 0 auto;
  box-sizing: border-box;
  overflow: hidden;
  height: 100vh;
  max-height: 100vh;
}

.game-title {
  font-size: 3em;
  color: #2c3e50;
  margin-bottom: 28px;
  text-align: center;
  font-weight: bold;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  flex-shrink: 0;
}

.icon {
  font-size: 1.2em;
  animation: bounce 1s infinite;
}

.game-rules {
  background: #f8f9fa;
  padding: 0;
  border-radius: 22px;
  margin-bottom: 28px;
  width: 100%;
  box-sizing: border-box;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.09);
  overflow: hidden;
  flex-shrink: 0;
}

.rules-header {
  background: #2196f3;
  padding: 24px 32px;
  color: white;
}

.rules-header h3 {
  margin: 0;
  font-size: 2em;
  display: flex;
  align-items: center;
  gap: 16px;
}

.rules-content {
  padding: 32px;
}

.rule-item {
  display: flex;
  align-items: flex-start;
  gap: 22px;
  margin-bottom: 22px;
  padding: 18px;
  background: white;
  border-radius: 14px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
  transition: transform 0.2s;
}

.rule-item:hover {
  transform: translateX(5px);
}

.rule-icon {
  font-size: 2em;
  min-width: 40px;
  text-align: center;
  flex-shrink: 0;
}

.rule-item p {
  margin: 0;
  color: #2c3e50;
  font-size: 1.5em;
  line-height: 1.7;
  text-align: left;
}

.status-section {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  gap: 16px;
}

.user-identity {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  background: #f5f5f5;
  border-radius: 20px;
  font-size: 0.9em;
  color: #666;
}

.reset-identity-btn {
  padding: 4px 8px;
  background: #e0e0e0;
  border: none;
  border-radius: 12px;
  font-size: 0.8em;
  color: #666;
  cursor: pointer;
  transition: all 0.2s;
}

.reset-identity-btn:hover {
  background: #d0d0d0;
  color: #333;
}

.phase-card {
  width: 100%;
  max-width: 260px;
  margin: 0 auto;
}

.players-section {
  justify-content: center;
  gap: 8px;
}

.status-card {
  background: white;
  padding: 22px;
  border-radius: 18px;
  flex: 1;
  min-width: 160px;
  max-width: 260px;
  text-align: center;
  transition: all 0.3s ease;
  border: 2px solid transparent;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.09);
}

.status-card.active {
  background: #e3f2fd;
  border-color: #2196f3;
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(33, 150, 243, 0.2);
}

.status-card h3 {
  margin: 0;
  color: #2c3e50;
  font-size: 1.7em;
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

.status-card p {
  margin: 0;
  color: #666;
  font-size: 1.3em;
}

.mine-count {
  margin-top: 5px !important;
  color: #2196f3 !important;
  font-weight: 500;
}

.board {
  display: grid;
  gap: 8px;
  background-color: #e0e0e0;
  padding: 8px;
  border-radius: 16px;
  box-shadow: inset 0 4px 16px rgba(0, 0, 0, 0.13);
  width: 100%;
  max-width: min(600px, 95vw);
  margin: 0 auto;
  aspect-ratio: 1;
  flex: 1;
  min-height: 0;
}

.row {
  display: flex;
  gap: 8px;
  width: 100%;
}

.cell {
  flex: 1;
  aspect-ratio: 1;
  background-color: #f5f5f5;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: clamp(40px, 10vw, 60px);
  transition: all 0.2s ease;
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.13);
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  position: relative;
  overflow: hidden;
}

.cell::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.1);
  opacity: 0;
  transition: opacity 0.2s;
}

.cell:hover::after {
  opacity: 1;
}

.cell.placing {
  background-color: #e3f2fd;
}

.cell.revealed {
  cursor: default;
  opacity: 0.85;
}

.cell.mine {
  background-color: #ffebee;
}

.cell.player1-mine {
  background-color: #ffcdd2;
}

.cell.player2-mine {
  background-color: #ffe0b2;
}

.mine-icon {
  font-size: 1.2em;
}

.safe-icon {
  font-size: 1.2em;
  color: #4CAF50;
}

@media (max-width: 900px) {
  .game-container {
    padding: 24px 2vw;
    gap: 18px;
    border-radius: 16px;
    max-width: 100vw;
  }
  .game-title {
    font-size: 2em;
    margin-bottom: 14px;
  }
  .rules-header {
    padding: 14px 10px;
    font-size: 1.2em;
  }
  .rules-content {
    padding: 14px;
  }
  .rule-item {
    padding: 10px;
    gap: 10px;
    margin-bottom: 10px;
  }
  .rule-icon {
    font-size: 1.2em;
    min-width: 24px;
  }
  .rule-item p {
    font-size: 1.1em;
  }
  .status-section {
    gap: 10px;
    margin-bottom: 14px;
  }
  .status-card {
    padding: 10px;
    min-width: 100px;
    max-width: 140px;
    border-radius: 10px;
  }
  .status-card h3 {
    font-size: 1.1em;
    margin-bottom: 6px;
  }
  .status-card p {
    font-size: 0.95em;
  }
  .board {
    gap: 4px;
    padding: 4px;
    border-radius: 8px;
    max-width: min(98vw, 400px);
  }
  .cell {
    font-size: clamp(24px, 7vw, 36px);
    border-radius: 6px;
  }
}

.fade-scale-enter-active, .fade-scale-leave-active {
  transition: all 0.35s cubic-bezier(.4,2,.6,1);
}
.fade-scale-enter-from, .fade-scale-leave-to {
  opacity: 0;
  transform: scale(0.7);
}

.game-over-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background: rgba(0,0,0,0.28);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
}
.game-over-content {
  background: #fff;
  color: #e53935;
  font-size: 2.2em;
  font-weight: bold;
  padding: 48px 70px 36px 70px;
  border-radius: 32px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.18);
  text-align: center;
  min-width: 320px;
  max-width: 90vw;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
}
.game-over-icon {
  font-size: 3.2em;
  margin-bottom: 6px;
  animation: pop-bounce 0.7s cubic-bezier(.4,2,.6,1);
}
@keyframes pop-bounce {
  0% { transform: scale(0.5); }
  60% { transform: scale(1.2); }
  100% { transform: scale(1); }
}
.game-over-title {
  font-size: 1.3em;
  color: #e53935;
  font-weight: 700;
  letter-spacing: 2px;
  margin-bottom: 2px;
}
.game-over-msg {
  font-size: 0.9em;
  color: #444;
  font-weight: 400;
  white-space: pre-line;
  line-height: 1.6;
}

.punishment-text {
  font-size: 1.2em;
  color: #e53935;
  font-weight: 700;
  margin-top: 8px;
  padding: 12px 24px;
  background: #fff3f3;
  border-radius: 16px;
  border: 2px dashed #e53935;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.05); }
  100% { transform: scale(1); }
}

.restart-btn {
  margin-top: 18px;
  padding: 10px 26px;
  font-size: 1.05em;
  font-weight: 600;
  color: #fff;
  background: linear-gradient(100deg, #43e97b 0%, #38f9d7 100%);
  border: none;
  border-radius: 20px;
  box-shadow: 0 3px 12px rgba(67,233,123,0.15), 0 1px 3px rgba(56,249,215,0.08);
  cursor: pointer;
  transition: background 0.18s, transform 0.13s, box-shadow 0.13s;
  outline: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  letter-spacing: 0.5px;
  position: relative;
  overflow: hidden;
  white-space: nowrap;
}
.restart-btn::before {
  content: '';
  position: absolute;
  left: 0; top: 0; right: 0; bottom: 0;
  background: linear-gradient(120deg,rgba(255,255,255,0.13) 0%,rgba(255,255,255,0.03) 100%);
  border-radius: 20px;
  pointer-events: none;
}
.restart-btn:hover {
  background: linear-gradient(100deg, #38f9d7 0%, #43e97b 100%);
  transform: translateY(-1px) scale(1.04);
  box-shadow: 0 6px 18px rgba(67,233,123,0.18), 0 1.5px 6px rgba(56,249,215,0.10);
}
.restart-btn:active {
  transform: scale(0.97);
  box-shadow: 0 1.5px 6px rgba(67,233,123,0.10);
}
.restart-btn .icon {
  font-size: 1.1em;
  margin-right: 2px;
}

.toast-bar {
  position: fixed;
  top: 28%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: linear-gradient(100deg, #43e97b 0%, #38f9d7 100%);
  color: #fff;
  font-size: 1.35em;
  font-weight: 600;
  padding: 28px 64px;
  border-radius: 32px;
  box-shadow: 0 8px 32px rgba(67,233,123,0.18), 0 2px 8px rgba(56,249,215,0.13);
  z-index: 20001;
  letter-spacing: 1.5px;
  animation: toast-pop-center 0.35s cubic-bezier(.4,2,.6,1);
  text-align: center;
  min-width: 480px;
  max-width: 90vw;
  pointer-events: none;
  white-space: nowrap;
}
@keyframes toast-pop-center {
  0% { transform: translate(-50%, -50%) scale(0.7); opacity: 0; }
  80% { transform: translate(-50%, -50%) scale(1.08); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}
.toast-fade-enter-active, .toast-fade-leave-active {
  transition: opacity 0.3s;
}
.toast-fade-enter-from, .toast-fade-leave-to {
  opacity: 0;
}

.connection-status {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 8px 16px;
  background: #f5f5f5;
  border-radius: 20px;
  margin-bottom: 16px;
  font-size: 0.9em;
  color: #666;
}

.connection-status.connected {
  background: #e8f5e9;
  color: #2e7d32;
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #666;
}

.connected .status-dot {
  background: #2e7d32;
  animation: pulse 2s infinite;
}

.room-actions {
  background: #f8f9fa;
  padding: 24px;
  border-radius: 16px;
  margin-bottom: 24px;
}

.action-buttons {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.action-btn {
  padding: 12px 24px;
  border: none;
  border-radius: 12px;
  font-size: 1.1em;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: all 0.2s;
}

.action-btn.create {
  background: #2196f3;
  color: white;
}

.action-btn.join {
  background: #4caf50;
  color: white;
}

.action-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}

.join-room {
  display: flex;
  gap: 8px;
}

.join-room input {
  flex: 1;
  padding: 12px;
  border: 2px solid #e0e0e0;
  border-radius: 12px;
  font-size: 1em;
  outline: none;
  transition: border-color 0.2s;
}

.join-room input:focus {
  border-color: #2196f3;
}

.waiting-screen {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255,255,255,0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.waiting-content {
  text-align: center;
  padding: 32px;
  background: white;
  border-radius: 24px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.1);
}

.loading-spinner {
  width: 48px;
  height: 48px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #2196f3;
  border-radius: 50%;
  margin: 0 auto 16px;
  animation: spin 1s linear infinite;
}

.room-id {
  margin-top: 16px;
  padding: 8px 16px;
  background: #f5f5f5;
  border-radius: 12px;
  font-family: monospace;
  font-size: 1.2em;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.player-status {
  margin-top: 8px !important;
  color: #2196f3 !important;
  font-weight: 500;
  font-size: 1.1em !important;
  padding: 4px 8px;
  background: rgba(33, 150, 243, 0.1);
  border-radius: 8px;
}
</style> 